import {
	App,
	Notice,
	Editor,
	MarkdownView,
	Modal,
	Plugin,
	PluginSettingTab,
	Setting,
	TFile,
	addIcon
} from 'obsidian';
// @ts-ignore
import crypto from 'crypto';
// @ts-ignore
import SparkMD5 from "spark-md5";

// Remember to rename these classes and interfaces!

interface ArticlePublishPluginSettings {
	// 发布地址
	publishUrl: string;
	// 用户令牌
	apiKey: string;
	// 用户密钥
	apiSecret: string;
	// 是否发布
	isPublish: string,
	// 是否转载
	isOriginal: string,
	// 开启评论
	openComment: string,
	// 标签
	tagUid: string,
	// 博客分类
	blogSortUid: string
	// 文章来源地址
	articlesPart: string
	// 作者
	author: string

}

// @ts-ignore
// @ts-ignore
const DEFAULT_SETTINGS: { publishUrl: string, apiKey: string , apiSecret: string, isPublish: string, openComment: string, tagUid: string, blogSortUid: string, isOriginal: string} = {
	publishUrl: 'http://localhost:8607/mogu-web/openapi',
	// 用户令牌
	apiKey: '',
	// 用户密钥
	apiSecret: '',
	// 是否发布
	isPublish: '1',
	// 开启评论
	openComment: '1',
	// 是否原创
	isOriginal: '1',
	// 标签
	tagUid: '',
	// 博客分类
	blogSortUid: ''
}

export default class ArticlePublishPlugin extends Plugin {
	settings: ArticlePublishPluginSettings;
	tagList: any[] = []
	blogSortList: any[] = []
	// 软件版本【当前版本0.0.2】
	publish_plugin_version = "0.0.2"

	async onload() {
		await this.loadSettings();
		// 获取相关数据
		await this.getTagList()
		await this.getBlogSortList()

		addIcon( "moguIcon", `<svg t="1723077191538" class="icon" viewBox="0 0 1024 1024" publish_plugin_version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5777" width="100" height="100"><path d="M594.944 573.91104c-13.28128 0-26.76736-0.1024-40.42752-0.1024h-85.03296c-13.66016 0-27.15648 0.1024-40.42752 0.1024-102.58432 0-200.3968 40.01792-270.40768 16.57856C79.31904 563.9168 51.2 522.00448 51.2 440.69888c0-47.33952 10.99776-107.71456 31.73376-154.7264 21.57568-48.91648 52.51072-93.2864 91.9552-131.85024 42.15808-41.23648 81.5104-73.68704 137.60512-96.39936C373.56544 32.9728 440.66816 20.48 512 20.48c70.18496 0 136.57088 12.50304 197.40672 37.24288 55.94112 22.7328 95.3856 55.23456 137.8304 96.39936 39.29088 38.11328 71.4752 83.6608 93.10208 131.74784 21.22752 47.2064 32.4608 107.6224 32.4608 154.8288 0 81.3056-28.11904 112.7424-107.44832 139.30496-70.58432 12.16512-167.8336-6.0928-270.40768-6.0928zM512 540.5696c14.35648 0 28.61056 0.1024 42.62912 0.1024h51.63008c183.26528 0 333.24032 41.91232 333.24032-99.96288 0-87.83872-43.20256-192.72704-115.5072-262.87104C741.41696 97.75104 637.3888 53.72928 512 53.72928c-270.52032 0-417.024 205.90592-427.49952 386.9696 0 67.06176 18.8928 96.27648 84.72576 118.3232 65.23904 21.84192 164.74112-18.36032 259.82976-18.36032h40.32512c14.0288 0 28.2624-0.1024 42.61888-0.1024z" fill="#2c2c2c" p-id="5778"></path><path d="M537.76384 1003.52h-3.98336c-90.0096-0.55296-256.44032-9.6768-293.44768-49.29536-31.45728-33.6896-20.09088-36.352-15.50336-100.39296 0-0.50176 15.50336-88.63744 15.50336-88.63744l29.22496-89.26208s32.43008-101.03808 35.91168-105.3184c7.03488-16.66048 14.5408-7.34208 23.35744-9.96352 8.8064-2.63168 7.84384 1.1776 10.47552 9.96352 0.65536 2.17088-33.82272 105.3184-33.82272 105.3184l-35.93216 115.16928s-27.6992 120.2176-4.9152 140.46208c43.56096 38.7072 189.91104 38.4512 271.23712 38.7072 117.9648 0 200.2432-28.95872 200.2432-28.95872s16.6912-3.51232 23.1424-20.13184c10.15808-26.1632 0-93.35808 0-93.35808 0-0.77824-13.84448-72.38656-37.376-139.7248-21.26848-60.81536-55.12192-115.63008-54.5792-117.48352a16.77312 16.77312 0 0 1 20.74624-11.32544c8.79616 2.57024 20.65408-8.77568 18.11456 0-0.2048 0.77824 35.66592 78.9504 53.0944 128.80896 25.2928 72.33536 25.66144 103.0144 25.66144 103.0144s38.912 128.5632 0 163.10272c-35.51232 31.51872-186.6752 48.41472-246.10816 49.2032-0.32768 0-0.7168 0.1024-1.04448 0.1024z" fill="#2c2c2c" p-id="5779"></path></svg>`);

		// This creates an icon in the left ribbon.
		const ribbonIconEl = this.addRibbonIcon('moguIcon', '发布到蘑菇社区', async (evt: MouseEvent) => {
			new UploadArticleModel(this.app, this).open();
		});
		// Perform additional things with the ribbon
		ribbonIconEl.addClass('my-plugin-ribbon-class');

		// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
		// const statusBarItemEl = this.addStatusBarItem();
		// statusBarItemEl.setText('文章发布插件');

		// This adds a simple command that can be triggered anywhere
		this.addCommand({
			id: '发布当前笔记',
			name: '发布当前笔记',
			callback: () => {
				new UploadArticleModel(this.app, this).open();
			}
		});
		// This adds an editor command that can perform some operation on the current editor instance
		this.addCommand({
			id: 'sample-editor-command',
			name: 'Sample editor command',
			editorCallback: (editor: Editor, view: MarkdownView) => {
				console.log(editor.getSelection());
				editor.replaceSelection('Sample Editor Command');
			}
		});
		// This adds a complex command that can check whether the current state of the app allows execution of the command
		this.addCommand({
			id: 'open-sample-modal-complex',
			name: 'Open sample modal (complex)',
			checkCallback: (checking: boolean) => {
				// Conditions to check
				const markdownView = this.app.workspace.getActiveViewOfType(MarkdownView);
				if (markdownView) {
					// If checking is true, we're simply "checking" if the command can be run.
					// If checking is false, then we want to actually perform the operation.
					if (!checking) {
						new SampleModal(this.app).open();
					}

					// This command will only show up in Command Palette when the check function returns true
					return true;
				}
			}
		});

		// This adds a settings tab so the user can configure various aspects of the plugin
		this.addSettingTab(new SampleSettingTab(this.app, this));

		// If the plugin hooks up any global DOM events (on parts of the app that doesn't belong to this plugin)
		// Using this function will automatically remove the event listener when this plugin is disabled.
		this.registerDomEvent(document, 'click', (evt: MouseEvent) => {
			console.log('click', evt);
		});

		// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
		this.registerInterval(window.setInterval(() => console.log('setInterval'), 5 * 60 * 1000));
	}

	onunload() {

	}

	async loadSettings() {
		this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData());
	}

	async saveSettings() {
		await this.saveData(this.settings);
	}

	async getTagList() {
		const publishUrl = this.settings.publishUrl
		if (!publishUrl) {
			return
		}
		const url = publishUrl + '/mogu-web/openapi/article/tagList'

		try {
			const response = await fetch(url, {
				method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					"apiKey": this.settings.apiKey,
					"apiSecret": this.settings.apiSecret,
				},
			});
			if (!response.ok) {
				throw new Error(`Server responded with ${response.status}: ${response.statusText}`);
			}
			const result = await response.json();
			if (result.code == "success") {
				this.tagList = result.data
			}
			console.log('get blogSort list success:', this.tagList);
		} catch (error) {
			console.error('Upload failed:', error);
		}
	}

	async getBlogSortList() {
		const publishUrl = this.settings.publishUrl
		if (!publishUrl) {
			return
		}
		const url = publishUrl + '/mogu-web/openapi/article/sortList'
		try {
			const response = await fetch(url, {
				method: 'GET',
				headers: {
					'Content-Type': 'application/json',
					"apiKey": this.settings.apiKey,
					"apiSecret": this.settings.apiSecret,
				},
			});
			if (!response.ok) {
				throw new Error(`Server responded with ${response.status}: ${response.statusText}`);
			}
			const result = await response.json();
			if (result.code == "success") {
				this.blogSortList = result.data
			}
			console.log('get blogSort list success:', this.blogSortList);
		} catch (error) {
			console.error('Upload failed:', error);
		}
	}

}

class SampleModal extends Modal {
	constructor(app: App) {
		super(app);
	}

	onOpen() {
		const {contentEl} = this;
		contentEl.setText('Woah!');
	}

	onClose() {
		const {contentEl} = this;
		contentEl.empty();
	}
}

class UploadArticleModel extends Modal {
	plugin: ArticlePublishPlugin;
	authorDiv: any
	originalDiv: any

	constructor(app: App, plugin: ArticlePublishPlugin) {
		super(app);
		this.plugin = plugin
		this.authorDiv = null
		this.originalDiv = null
	}

	async onOpen() {
		const {contentEl} = this;

		new Setting(contentEl)
			.setName('文章标签')
			.setDesc('选择文章标签进行发布')
			.addDropdown(dropdown => {
				const tagList = this.plugin.tagList
				// 循环添加多个选项
				for (let i = 0; i < tagList.length; i++) {
					dropdown.addOption(tagList[i].uid, tagList[i].content);
				}

				// 设置默认值
				dropdown.setValue(this.plugin.settings.tagUid);

				// 监听下拉框值变化事件
				dropdown.onChange(async (value) => {
					// 更新插件设置中的值
					console.log("保存标签结果", value)
					this.plugin.settings.tagUid = value;
					await this.plugin.saveSettings();
				})
				// 设置下拉框的长度
				dropdown.selectEl.style.width = '300px';
				dropdown.selectEl.style.margin = '20px 0 0 0';
			});

		new Setting(contentEl)
			.setName('文章分类')
			.setDesc('设置文章分类')
			.addDropdown(dropdown => {
				// 循环添加多个选项
				const blogSortList = this.plugin.blogSortList
				for (let i = 0; i < this.plugin.blogSortList.length; i++) {
					dropdown.addOption(blogSortList[i].uid, blogSortList[i].sortName);
				}
				// 设置默认值
				dropdown.setValue(this.plugin.settings.blogSortUid);
				// 监听下拉框值变化事件
				dropdown.onChange(async (value) => {
					console.log("保存分类结果", value)
					// 更新插件设置中的值
					this.plugin.settings.blogSortUid = value;
					await this.plugin.saveSettings();
				})
				// 设置下拉框的长度
				dropdown.selectEl.style.width = '300px';
			});

		// 创建下拉框设置项
		new Setting(contentEl)
			.setName('是否发布')
			.setDesc('推送审核并发布')
			.addDropdown(dropdown => {
				dropdown
					.addOption('1', '发布')
					.addOption('0', '草稿');
				// 设置下拉框的默认值

				// 监听下拉框值变化事件
				dropdown.onChange(async (value) => {
					// 更新插件设置中的值
					this.plugin.settings.isPublish = value;
					await this.plugin.saveSettings();
				})

				// 设置下拉框的长度
				dropdown.selectEl.style.width = '300px';
			});

		new Setting(contentEl)
			.setName('开启评论')
			.setDesc('开启文章评论')
			.addDropdown(dropdown => {
				dropdown
					.addOption('1', '开启')
					.addOption('0', '关闭');

				// 监听下拉框值变化事件
				dropdown.onChange(async (value) => {
					// 更新插件设置中的值
					this.plugin.settings.openComment = value;
					await this.plugin.saveSettings();
				})

				// 设置下拉框的长度
				dropdown.selectEl.style.width = '300px';
			});

		new Setting(contentEl)
			.setName('是否原创')
			.setDesc('是否是原创文章')
			.addDropdown(dropdown => {
				dropdown
					.addOption('1', '原创')
					.addOption('0', '转载');

				// 监听下拉框值变化事件
				dropdown.onChange(async (value) => {
					// 更新插件设置中的值
					this.plugin.settings.isOriginal = value;
					await this.plugin.saveSettings();
					// 如果选择了转载，需要填写转载地址
					this.updateSecondSettingVisibility(value)
				})
				// 设置下拉框的长度
				dropdown.selectEl.style.width = '300px';
			});


		//新增提交按钮
		new Setting(contentEl)
			.addButton(button => {
				button
					.setButtonText('提交')
					.setCta()
					.onClick(async () => {

						// 获取当前文件的对象
						const currentFile = this.app.workspace.getActiveFile()
						console.log("当前激活的文件2", currentFile)
						if (currentFile) {
							this.uploadContent(currentFile)
						}
						this.close();
					});
			});
	}

	// 更新第二项
	updateSecondSettingVisibility(isOriginal: string) {
		const { contentEl } = this;
		const secondSettingDisplayed = isOriginal.trim() == '0'; // 假设当第一项不为空时显示第二项
		if (secondSettingDisplayed) {
			// 如果第二项尚未添加到DOM，添加它
			this.authorDiv = new Setting(contentEl)
				.setName('作者')
				.setDesc('请输入文章作者')
				.addText(text => {
					text.setPlaceholder('请输入文章作者')
					text.setValue(this.plugin.settings.author)
					text.onChange(async (value) => {
						this.plugin.settings.author = value;
						await this.plugin.saveSettings();
					})
					// 设置长度
					text.inputEl.style.width = '300px'
				});

			this.originalDiv = new Setting(contentEl)
				.setName('文章出处')
				.setDesc('请输入文章来源地址')
				.addText(text => {
					text.setPlaceholder('请输入文章来源地址')
					text.setValue(this.plugin.settings.articlesPart)
					text.onChange(async (value) => {
						this.plugin.settings.articlesPart = value;
						await this.plugin.saveSettings();
					})
					// 设置长度
					text.inputEl.style.width = '300px'
				});
		} else if (!secondSettingDisplayed) {
			this.authorDiv.settingEl.style.display = 'none';
			this.originalDiv.settingEl.style.display = 'none';
			this.authorDiv = null;
			this.authorDiv = null;
		}
	}


	// 获取markdown文件
	private async readMarkdownContent(file: TFile): Promise<string> {
		try {
			const fileContent = await this.app.vault.read(file);
			// 获取文件标题
			return fileContent;
		} catch (error) {
			console.error('Error reading file:', error);
			return '';
		}
	}

	async extractImagesFromFile(currentFile: TFile, content: string): Promise<Map<string, string>> {
		// 正则表达式匹配Markdown图片标签
		const imageRegex = /!\[.*?\]\((.*?)\)/g;
		const fileNameList: string[] = [];
		// 使用正则表达式查找所有markdown标签
		let match;
		while ((match = imageRegex.exec(content))!== null) {
			const linkText = match[1];
			// 判断是否是http域名
			if (linkText.startsWith('http')) {
				continue;
			}
			fileNameList.push(linkText);
		}
		const allFileList = currentFile.vault.getFiles()

		// 使用正则表达式查找双链标签
		const imageRegex2 = /!\[\[(.*?)\]\]/g;
		while ((match = imageRegex2.exec(content)) !== null) {
			const linkText = match[1]; // 提取链接文本，例如 "Pasted image 20240727101045.png"
			// 判断是否是http域名
			if (match[1].startsWith('http')) {
				continue;
			}
			// 根据linkText 获取Obsidian中的文件对象
			console.log("获取的文件路径", linkText)
			fileNameList.push(linkText); // 添加到结果数组
		}
		console.log("所有文件夹", allFileList)
		console.log("需要匹配的文件列表", fileNameList)

		const imageMap: Map<string, string> = new Map();

		for (let j = fileNameList.length - 1; j >= 0; j--) {
			for (let i = allFileList.length - 1; i >= 0; i--) {
				const oldFileName = fileNameList[j]
				const fileName = oldFileName.split('/').pop()
				// 判断是否包括了文件名【因为fileName可能是比较长的，带目录结构】
				// @ts-ignore
				if (allFileList[i].name.contains(fileName)) {
					console.log("匹配到的文件名", allFileList[i].name)
					console.log("要匹配到的文件名", fileName)
					console.log("匹配到的文件夹", allFileList[i])
					// 上传文件
					const picture = await this.uploadFile(allFileList[i])
					if (picture != null) {
						console.log("开始上传", oldFileName, picture.pictureUrl)
						imageMap.set(oldFileName, picture.pictureUrl)
					}
					break
				}
			}
		}
		return imageMap;
	}

	/**
	 * 获取文件的MD5码
	 * @param blob
	 */
	async getFileMD5(blob: Blob): Promise<any> {
		// 上传前判断一下文件是否在服务器已存在
		const fileReader = new FileReader();
		const Spark = new SparkMD5.ArrayBuffer();
		fileReader.readAsArrayBuffer(blob);
		return new Promise((resolve, reject) => {
			fileReader.onload = function (e) {
				// @ts-ignore
				Spark.append(e.target.result);
				const md5 = Spark.end();
				resolve(md5);
			};
			fileReader.onerror = function (err) {
				reject(err);
			};
		});

	}
	/**
	 *
	 * @param imageMap
	 * @param file
	 */
	async uploadFile(file: TFile): Promise<any> {
		if (!this.plugin.settings.publishUrl) {
			throw new Error('未设置服务器发布地址');
		}
		// 读取图片文件内容
		const fileContent = await this.app.vault.readBinary(file);
		// 假设文件是PNG图片
		const blob = new Blob([fileContent], { type: 'image/png' });
		const fileMd5 = await this.getFileMD5(blob);
		console.log("获取MD5码", fileMd5)
		if (fileMd5) {
			const checkFormData = new FormData();
			const array = []
			array.push(fileMd5)
			// @ts-ignore
			checkFormData.append("md5List", JSON.stringify(array))
			console.log("获取数据", checkFormData)
			const checkResp = await fetch(this.plugin.settings.publishUrl + '/mogu-picture/file/getFileByMD5', {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
					"apiKey": this.plugin.settings.apiKey,
					"apiSecret": this.plugin.settings.apiSecret,
					"publish_plugin_version": this.plugin.publish_plugin_version,
				},
				body: JSON.stringify(array),
			});
			if (!checkResp.ok) {
				throw new Error(`上传失败: ${checkResp.statusText}`);
			}
			const result = await checkResp.json();
			console.log("前置校验获取的数据", result.data)
			if (result.code == "success") {
				const pictureMap = result.data
				for (const key in pictureMap) {
					if (!pictureMap.hasOwnProperty(key)) {
						continue
					}
					const file = pictureMap[key]
					console.log("通过MD5获取到重复文件", file)
					if (file) {
						const fileImage = {
							"uid": file.uid,
							"fileOldName": file.fileOldName,
							"pictureUrl": file.pictureUrl
						}
						return fileImage
					}
				}
			}
		}

		// 创建FormData对象，用于构建表单数据
		const formData = new FormData();
		formData.append('filedatas', blob, file.basename);

		// 创建HTTP请求
		const response = await fetch(this.plugin.settings.publishUrl + '/mogu-picture/file/uploadFile', {
			method: 'POST',
			headers: {
				"apiKey": this.plugin.settings.apiKey,
				"apiSecret": this.plugin.settings.apiSecret,
				"publish_plugin_version": this.plugin.publish_plugin_version,
			},
			body: formData,
		});
		if (!response.ok) {
			throw new Error(`上传失败: ${response.statusText}`);
		}
		const result = await response.json();
		if (result.code != "success") {
			return null
		}
		console.log("输出的数据", result.data)
		const pictureList = result.data
		const fileImage = {
			"uid": pictureList[0].uid,
			"fileOldName": pictureList[0].fileOldName,
			"picUrl": pictureList[0].picUrl,
			"qiNiuUrl": pictureList[0].qiNiuUrl,
			"minioUrl": pictureList[0].minioUrl,
			"pictureUrl": pictureList[0].pictureUrl
		}
		return fileImage
	}


	/**
	 * 加密时间戳
	 * @param timestamp
	 * @private
	 */
	// eslint-disable-next-line no-mixed-spaces-and-tabs
	 private async generateTimestampHash(timestamp: number): Promise<string> {
		// 将时间戳转换为字符串
		const timestampStr = timestamp.toString();
		// 创建一个SHA-256哈希实例
		const hash = crypto.createHash('sha256');
		// 更新哈希实例，传入时间戳字符串
		hash.update(timestampStr);
		// 生成哈希摘要
		const hashDigest = hash.digest('hex');
		// 截断哈希值以获得32位的字符串
		const encryptedTimestampString = hashDigest.substring(0, 32);
		return encryptedTimestampString;
	}


	// 上传文章到服务器
	private async uploadContent(currentFile: TFile) {
		const url = this.plugin.settings.publishUrl + '/mogu-web/openapi/article/publish'
		const tagUid = this.plugin.settings.tagUid
		const blogSortUid = this.plugin.settings.blogSortUid
		const isOriginal = this.plugin.settings.isOriginal
		const author = this.plugin.settings.author
		const isPublish = this.plugin.settings.isPublish
		const articlesPart = this.plugin.settings.articlesPart
		const openComment = this.plugin.settings.openComment

		// 获取当前文件的内容和标题
		let content = await this.readMarkdownContent(currentFile)

		// 使用正则表达式解析文件内容中所有的图片
		const imageMap = await this.extractImagesFromFile(currentFile, content)

		let mapString = '';
		for (const [key, value] of imageMap) {
			if (mapString) mapString += ', ';
			mapString += `"${key}": "${value}"`;
		}
		mapString = "{" + mapString + "}"

		// 将文本转化成标准的markdown
		content = content.replace(/!\[\[(.*?)\]\]/g, '![]($1)');

		console.log("当前文件里所有的图片", mapString)
		const title = currentFile.basename
		// 获取当前文件的创建时间，作为幂等键
		const idempotentKey = await this.generateTimestampHash(currentFile.stat.ctime)
		try {
			const response = await fetch(url, {
				method: 'POST',
				headers: {
					'Content-Type': 'application/json',
					"apiKey": this.plugin.settings.apiKey,
					"apiSecret": this.plugin.settings.apiSecret,
					"publish_plugin_version": this.plugin.publish_plugin_version,
				},
				body: JSON.stringify({
					"title": title,
					"content": content,
					"tagUid": tagUid,
					"blogSortUid": blogSortUid,
					"isOriginal": isOriginal,
					"author": author,
					"articlesPart": articlesPart,
					"isPublish": isPublish,
					"idempotentKey": idempotentKey,
					"openComment": openComment,
					"pictureMap": mapString,
				}),
			});
			if (!response.ok) {
				throw new Error(`Server responded with ${response.status}: ${response.statusText}`);
			}
			const result = await response.json();

			new Notice(result.message);

			console.log('Upload successful:', result);
		} catch (error) {
			console.error('Upload failed:', error);
		}
	}

	onClose() {
		const {contentEl} = this;
		contentEl.empty();
	}
}


class SampleSettingTab extends PluginSettingTab {
	plugin: ArticlePublishPlugin;

	constructor(app: App, plugin: ArticlePublishPlugin) {
		super(app, plugin);
		this.plugin = plugin;
	}

	display(): void {
		const {containerEl} = this;

		containerEl.empty();

		new Setting(containerEl)
			.setName('社区API地址')
			.setDesc('输入完整API路径，例如: https://gateway.moguit.cn')
			.addText(text => {
				text.setPlaceholder('输入后台url')
				text.setValue(this.plugin.settings.publishUrl)
				text.onChange(async (value) => {
					this.plugin.settings.publishUrl = value;
					await this.plugin.getTagList()
					await this.plugin.getBlogSortList()
					await this.plugin.saveSettings();
				})
				// 设置长度
				text.inputEl.style.width = '300px'
			});

		new Setting(containerEl)
			.setName('ApiKey')
			.setDesc('打开个人中心，获取API令牌')
			.addText(text => {
				text.setPlaceholder('请输入令牌')
				text.setValue(this.plugin.settings.apiKey)
				text.onChange(async (value) => {
					this.plugin.settings.apiKey = value;
					await this.plugin.getTagList()
					await this.plugin.getBlogSortList()
					await this.plugin.saveSettings();
				})
				// 设置长度
				text.inputEl.style.width = '300px'
			});


		new Setting(containerEl)
			.setName('ApiSecret')
			.setDesc('打开个人中心，获取API密钥')
			.addText(text => {
				text.setPlaceholder('请输入密钥')
				text.setValue(this.plugin.settings.apiSecret)
				text.onChange(async (value) => {
					this.plugin.settings.apiSecret = value;
					await this.plugin.getTagList()
					await this.plugin.getBlogSortList()
					await this.plugin.saveSettings();
				})
				// 设置长度
				text.inputEl.style.width = '300px'
			});
	}


}
